package com.hippomeetsskunk.savanna.model;

import java.util.Random;

public class MarkovModel {

	private Random random = new Random();
	
	public double next(double previous, double expectation, double variation){
		
		while(true){
			// 1. get variation on last
			final double d = random.nextGaussian() * variation;
			final double n = previous + d;
			
			// 2. accept if closer to expectation
			if (Math.abs(n-expectation) < Math.abs(previous - expectation)) return n;
			
			// 3. otherwise accept sometimes
			// quantile(p) = -ln(1-p) / lambda
			final double lambda = -Math.log(1.0 - 0.5) / variation;
			final double p = Math.exp(-lambda * Math.abs(n - expectation));
			
			if (random.nextDouble() < p){
				return n;
			}
		}
		
	}
}
